package savet.gui.util;

import java.awt.Color;
import java.awt.Component;
import java.util.Date;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import org.apache.commons.collections.EnumerationUtils;
import savet.entidades.Trabalhador;
import savet.entidades.atributos.ASOS;
import savet.entidades.atributos.Atributo;
import savet.entidades.atributos.CAGED;
import savet.entidades.atributos.Ferias;
import savet.entidades.atributos.LRE;
import savet.entidades.atributos.Rais;
import savet.entidades.atributos.Rescisao;
import savet.gui.modelos.ModeloExamesMedicos;
import savet.gui.modelos.ModeloFerias;
import savet.gui.modelos.ModeloLRE;
import savet.gui.modelos.ModeloRaisCaged;
import savet.gui.modelos.ModeloRescisao;
import savet.gui.modelos.ModeloSalarioAtributo;
import savet.gui.modelos.ModeloVinculos;
import savet.gui.tabelas.AtributoCellEditor;
import savet.gui.tabelas.AtributoCellRenderer;
import savet.gui.tabelas.AtributoDataCellRenderer;
import savet.gui.tabelas.DateCellEditor;
import savet.gui.tabelas.DateCellRenderer;
import savet.gui.tabelas.NewDefaultTableModel;
import savet.gui.tabelas.SimplesCellRenderer;
import savet.gui.tabelas.group.JTableGroupableHeader;
import savet.gui.tabelas.salario.editor.AlteracaoFuncaoCellEditor;
import savet.gui.tabelas.salario.editor.AlteracaoRemuneracaoEditor;
import savet.gui.tabelas.salario.editor.DependentesCellEditor;
import savet.gui.tabelas.salario.editor.HoraExtraCellEditor;
import savet.gui.tabelas.salario.editor.ValeTransporteCellEditor;
import savet.gui.tabelas.salario.renderer.AtributoSalarioCellRenderer;
import savet.util.ListaTrabalhadores;
import savet.util.SauditaLog;
import savet.util.Trabalhadores;

/**
 *
 * @author Adisson Marinho
 */
public final class GeradorTabelasUtil {

    private static List<Trabalhador> trabalhadores;
    private static ModeloRescisao dtmRescisao;
    private static ModeloFerias dtmFerias;
    private static ModeloRaisCaged dtmRaisCaged;
    private static ModeloExamesMedicos dtmExamMed;
    private static ModeloLRE dtmRegistro;
    private static ModeloVinculos dtmTrabalhadores;
    private static ModeloSalarioAtributo dtmSalarioAtributos;

    static {
        trabalhadores = ListaTrabalhadores.getInstance().getTrabalhadores();
    }

    private static void definirBordaCalendario(Object idColuna, AtributoDataCellRenderer cellRenderer) {
        BordaLinhaCustomizada borda = null;
        if (idColuna.equals("Dez")) {
            borda = new BordaLinhaCustomizada(new Color(50, 50, 50), .6);
            borda.setLarguraDireita(1.2);
        } else if (idColuna.equals("Jan")) {
            borda = new BordaLinhaCustomizada(new Color(50, 50, 50), .6);
            borda.setLarguraEsquerda(1.2);
        } else {
            borda = new BordaLinhaCustomizada(new Color(50, 50, 50), .6);
        }
        cellRenderer.setBorder(borda);
    }

    public static void gerarTablesSalarioAtributos(JTableGroupableHeader jTableSalarioAtributos) {
        dtmSalarioAtributos = new ModeloSalarioAtributo();
        ListaTrabalhadores.getInstance().adicionarObserver(dtmSalarioAtributos);
        jTableSalarioAtributos.setModel(dtmSalarioAtributos);

        TableColumnModel columnModel = jTableSalarioAtributos.getColumnModel();
        
        Enumeration<TableColumn> columns = columnModel.getColumns();
        while (columns.hasMoreElements()) {
            columns.nextElement().setCellRenderer(new AtributoSalarioCellRenderer());
        }

        // 2 Alt F. | 3 Alt Rem.
        // 4 Depend | 5 V. Trans
        // 7 H. Ext
        columnModel.getColumn(2).setCellEditor(new AlteracaoFuncaoCellEditor());
        columnModel.getColumn(3).setCellEditor(new AlteracaoRemuneracaoEditor());
        columnModel.getColumn(4).setCellEditor(new DependentesCellEditor());
        columnModel.getColumn(5).setCellEditor(new ValeTransporteCellEditor());
        columnModel.getColumn(7).setCellEditor(new HoraExtraCellEditor());

    }

    private GeradorTabelasUtil() {
    }

    public static void gerarTabelaExames(JTableGroupableHeader jTableExamMed, Date inicio, Date fim) {
//      LoteUtil loteUtil = LoteUtil.getInstance();
//
//            loteUtil.getEmpregadorAtual().setInicioPeriodoNotificado(inicio);
//            loteUtil.getEmpregadorAtual().setFimPeriodoNotificado(fim);

        Map<Integer, String> meses = PeriodoUtil.getMapMeses(inicio, fim);
        Map<Integer, String> anos = PeriodoUtil.getMapAnos(inicio, fim);

        dtmExamMed = new ModeloExamesMedicos(meses.values().toArray(), inicio, fim);
        ListaTrabalhadores.getInstance().adicionarObserver(dtmExamMed);

        jTableExamMed.setModel(dtmExamMed);

        for (int indice : anos.keySet()) {
            jTableExamMed.groupColumn(anos.get(indice), indice);
        }

        TableColumnModel columnModel = jTableExamMed.getColumnModel();

        List<TableColumn> list = EnumerationUtils.toList(columnModel.getColumns());
        for (TableColumn tableColumn : list) {
            AtributoDataCellRenderer cellRenderer = new AtributoDataCellRenderer();
            definirBordaCalendario(tableColumn.getIdentifier(), cellRenderer);
            tableColumn.setCellRenderer(cellRenderer);
            tableColumn.setCellEditor(new AtributoCellEditor(ASOS.class));
            tableColumn.setPreferredWidth(26);
        }

    }

    public static void gerarTabelaVinculos(JTableGroupableHeader jTableVinculos) {
        jTableVinculos.removeAll();
        dtmTrabalhadores = new ModeloVinculos();

        ListaTrabalhadores.getInstance().adicionarObserver(dtmTrabalhadores);
        jTableVinculos.setModel(dtmTrabalhadores);

        JTableUtil.criarMenuPopup(jTableVinculos);

        jTableVinculos.groupColumns(" ", 6);
        jTableVinculos.groupColumn("LRE", 7);

        // configurar largura das colunas
        TableColumnModel columnModel = jTableVinculos.getColumnModel();
        columnModel.getColumn(0).setPreferredWidth(180);
        columnModel.getColumn(1).setPreferredWidth(80);
        columnModel.getColumn(2).setPreferredWidth(65);
        columnModel.getColumn(3).setPreferredWidth(65);
        columnModel.getColumn(4).setPreferredWidth(37);
        columnModel.getColumn(5).setPreferredWidth(30);
        columnModel.getColumn(6).setPreferredWidth(33);
        columnModel.getColumn(7).setPreferredWidth(30);

        // coonfigurar renderers e editors
        columnModel.getColumn(4).setCellEditor(new DefaultCellEditor(new JComboBox(new Object[]{" ", "H", "U1", "U2", "I1", "I2", "I3", "N1", "J", "L"})));
        columnModel.getColumn(6).setCellEditor(new DefaultCellEditor(new JComboBox(new Object[]{" ", "M", "F"})));
        columnModel.getColumn(5).setCellEditor(new DefaultCellEditor(new JCheckBox()));

        jTableVinculos.setDefaultRenderer(Object.class, new SimplesCellRenderer());

        jTableVinculos.setDefaultEditor(Date.class, new DateCellEditor());
        jTableVinculos.setDefaultRenderer(Date.class, new DateCellRenderer());

        columnModel.getColumn(5).setCellRenderer(new javax.swing.table.TableCellRenderer() {

            private JCheckBox checkBox = new JCheckBox();

            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                Boolean valor = (Boolean) value;
                checkBox.setOpaque(false);
                checkBox.setSelected(valor);
                return checkBox;
            }
        });

        dtmTrabalhadores.addTableModelListener(new TableModelListener() {

            public void tableChanged(TableModelEvent e) {
                if (e.getType() == TableModelEvent.UPDATE) {
                    int firsRow = e.getFirstRow();
                    int lastRow = e.getLastRow();

                    if (firsRow == lastRow
                            && lastRow != Integer.MAX_VALUE) {
                        Trabalhador t = dtmTrabalhadores.getTrabalhador(firsRow);
                        System.out.println("ALterando trabalhador " + t.getNome());
                        ListaTrabalhadores.getInstance().notifyObservers(t);
                    }
                }
            }
        });
    }

    public static void gerarTabelaRegistro(final JTableGroupableHeader jTableRegistro) {
        try {
            dtmRegistro = //new NewDefaultTableModel("pg", " ", "CTPS");
                    new ModeloLRE();
            ListaTrabalhadores.getInstance().adicionarObserver(dtmRegistro);
            jTableRegistro.setModel(dtmRegistro);
            jTableRegistro.groupColumns("Livro de Registro", 1);

            TableColumnModel columnModel = jTableRegistro.getColumnModel();
            List<TableColumn> list = EnumerationUtils.toList(columnModel.getColumns());

            for (TableColumn tableColumn : list) {
                if (!tableColumn.getIdentifier().equals("Pg")) {
                    AtributoCellRenderer cellRenderer = new AtributoCellRenderer();
                    cellRenderer.setBorder(BorderFactory.createLineBorder(Color.gray));
                    tableColumn.setCellRenderer(cellRenderer);
                    tableColumn.setCellEditor(new AtributoCellEditor(LRE.class));
                } else {
                    SimplesCellRenderer cellRenderer = new SimplesCellRenderer();
                    tableColumn.setCellRenderer(cellRenderer);
                }
            }

            dtmRegistro.addTableModelListener(new TableModelListener() {

                public void tableChanged(TableModelEvent e) {
                    dtmTrabalhadores.fireTableDataChanged();
                }
            });

        } catch (RuntimeException ex) {
            SauditaLog.adicionarSevereLog(ex.getMessage(), ex);
        }
    }

    public static void gerarTabelaFerias(JTableGroupableHeader jTableFerias, Date inicio, Date fim) {
        try {
            Map<Integer, String> meses = PeriodoUtil.getMapMeses(inicio, fim);
            Map<Integer, String> anos = PeriodoUtil.getMapAnos(inicio, fim);

            dtmFerias = new ModeloFerias(meses.values().toArray(), inicio, fim);
            ListaTrabalhadores.getInstance().adicionarObserver(dtmFerias);

            jTableFerias.setModel(dtmFerias);

            for (int indice : anos.keySet()) {
                jTableFerias.groupColumn(anos.get(indice), indice);
            }

//            for (Trabalhador trabalhador : trabalhadores) {
//                adicionarFerias(trabalhador, inicio, fim);
//            }

            TableColumnModel columnModel = jTableFerias.getColumnModel();

            List<TableColumn> list = EnumerationUtils.toList(columnModel.getColumns());
            for (TableColumn tableColumn : list) {
                AtributoDataCellRenderer cellRenderer = new AtributoDataCellRenderer();
                Object idColuna = tableColumn.getIdentifier();

                definirBordaCalendario(idColuna, cellRenderer);

                tableColumn.setCellRenderer(cellRenderer);
                tableColumn.setCellEditor(new AtributoCellEditor(Ferias.class));
                tableColumn.setPreferredWidth(26);
            }

            // Adicionando PopupMenu para editar periodos de ferias e afastamento
            JPopupMenu popup = new JPopupMenu();
            popup.add(new FeriasItem(FeriasItem.PERIODOS_GOZO));
            popup.add(new FeriasItem(FeriasItem.PERIODOS_AFASTAMENTO));
            jTableFerias.add(popup);
            jTableFerias.addMouseListener(new MousePeriodosListener());

        } catch (Exception ex) {
            SauditaLog.adicionarSevereLog(ex.getMessage(), ex);
        }
    }

    public static void gerarTabelaRaisCAGED(JTableGroupableHeader jTableRaisCaged, Date inicio, Date fim) {
        try {
            for (Trabalhador trabalhador : trabalhadores) {
                adicionarRaisCaged(trabalhador, inicio, fim);
            }

            LinkedList<String> linkedMeses = PeriodoUtil.getListMeses(inicio, fim);
            LinkedList<String> linkedAnos = PeriodoUtil.getListAnosDosMeses(inicio, fim);

            linkedMeses.add(0, "Rais");
            linkedAnos.add(0, linkedAnos.get(0));

            for (int i = 0; i < linkedMeses.size(); i++) {
                if (linkedMeses.get(i).equalsIgnoreCase("Dez")) {
                    linkedMeses.add(i + 1, "Rais");
                    linkedAnos.add(i + 1, linkedAnos.get(i + 1));

                }
            }
//            dtmRaisCaged = new NewDefaultTableModel(linkedMeses.toArray());
            dtmRaisCaged = new ModeloRaisCaged(linkedMeses.toArray(), inicio, fim);
            ListaTrabalhadores.getInstance().adicionarObserver(dtmRaisCaged);
//            dtmRaisCaged.setNumRows(trabalhadores.size());

//            for (int i = 0; i < trabalhadores.size(); i++) {
//                int raisCount = 0;
//                int cagedCount = 0;
//                for (int j = 0; j < linkedMeses.size(); j++) {
//
//                    if (linkedMeses.get(j).equals("Rais")) {
//                        dtmRaisCaged.setValueAt(
//                                trabalhadores.get(i).
//                                getRais().
//                                getTodosAtributosData().get(raisCount++), i, j);
//
//                    } else {
//                        dtmRaisCaged.setValueAt(
//                                trabalhadores.get(i).
//                                getCaged().
//                                getAtributosData().get(cagedCount++), i, j);
//                    }
//                }
//            }

            jTableRaisCaged.setModel(dtmRaisCaged);
            for (int i = 0; i < linkedAnos.size(); i++) {
                jTableRaisCaged.groupColumn(linkedAnos.get(i), i);
            }

            TableColumnModel columnModel = jTableRaisCaged.getColumnModel();
            List<TableColumn> list = EnumerationUtils.toList(columnModel.getColumns());

            for (TableColumn tableColumn : list) {
                BordaLinhaCustomizada borda = new BordaLinhaCustomizada(new Color(50, 50, 50), .6);
                if (tableColumn.getIdentifier().equals("Rais")) {
                    tableColumn.setPreferredWidth(30);

                    AtributoDataCellRenderer cellRenderer = new AtributoDataCellRenderer();
                    borda.setLarguraEsquerda(1.2);
                    cellRenderer.setBorder(borda);
                    tableColumn.setCellRenderer(cellRenderer);
                    tableColumn.setCellEditor(new AtributoCellEditor(Rais.class));
                } else {
                    AtributoDataCellRenderer cellRenderer = new AtributoDataCellRenderer();
                    cellRenderer.setBorder(borda);
                    if (tableColumn.getIdentifier().equals("Dez")) {
                        borda.setLarguraDireita(1.2);
                    }
                    tableColumn.setCellRenderer(cellRenderer);
                    tableColumn.setCellEditor(new AtributoCellEditor(CAGED.class));
                    tableColumn.setPreferredWidth(26);
                }
            }
        } catch (RuntimeException ex) {
            SauditaLog.adicionarSevereLog(ex.getMessage(), ex);
        }
    }

    public static void gerarTabelaRescisao(JTableGroupableHeader jTableRescisao, Date inicio, Date fim) {

        for (Trabalhador trabalhador : trabalhadores) {
            adicionarRescisao(trabalhador, inicio, fim);
        }
        List<String> linkedAnos = PeriodoUtil.getListAnos(inicio, fim);
        List<String> headerRescisao = new LinkedList<String>();

        for (int i = 0; i < linkedAnos.size(); i++) {
            headerRescisao.add("Avi. Pre.");
            headerRescisao.add("Ped. Dem.");
            headerRescisao.add("Ter. Resc.");

        }

        dtmRescisao = new ModeloRescisao(headerRescisao.toArray(), inicio, fim);
        ListaTrabalhadores.getInstance().adicionarObserver(dtmRescisao);
//        dtmRescisao.setNumRows(trabalhadores.size());
        jTableRescisao.setModel(dtmRescisao);


        for (int i = 0; i < linkedAnos.size(); i++) {
            if (i == 0) {
                jTableRescisao.groupColumns(linkedAnos.get(i), 0, 2);
            } else {
                jTableRescisao.groupColumns(linkedAnos.get(i), i * 3, i * 3 + 2);
            }
        }

        for (int i = 0; i < trabalhadores.size(); i++) {
            int countAp = 0;
            int countPD = 0;
            int countTR = 0;

            for (int j = 0; j < headerRescisao.size(); j++) {
                if (headerRescisao.get(j).equals("Avi. Pre.")) {
                    jTableRescisao.setValueAt(trabalhadores.get(i).getRescisao().getAvisoPrevio().get(countAp), i, j);
                    countAp++;
                } else if (headerRescisao.get(j).equals("Ped. Dem.")) {
                    jTableRescisao.setValueAt(trabalhadores.get(i).getRescisao().getPedidoDemissao().get(countPD), i, j);
                    countPD++;
                } else if (headerRescisao.get(j).equals("Ter. Resc.")) {
                    jTableRescisao.setValueAt(trabalhadores.get(i).getRescisao().getTermo().get(countTR), i, j);
                    countTR++;
                }
            }
        }

        TableColumnModel columnModel = jTableRescisao.getColumnModel();
        List<TableColumn> list = EnumerationUtils.toList(columnModel.getColumns());

        for (TableColumn tableColumn : list) {

            AtributoDataCellRenderer cellRenderer = new AtributoDataCellRenderer();
            cellRenderer.setBorder(new BordaLinhaCustomizada(new Color(50, 50, 50), .6));
            tableColumn.setCellRenderer(cellRenderer);
            tableColumn.setCellEditor(new AtributoCellEditor(Rescisao.class));
            tableColumn.setPreferredWidth(65);

        }
    }

    public static void adicionarExamesMedicos(Trabalhador trabalhador, Date inicio, Date fim) {
//        ASOS examMed = new ASOS();
//        examMed.setTrabalhador(trabalhador);
//        examMed.setAtributosData(Trabalhadores.getListaAtributoMeses(inicio, fim));
//        trabalhador.setExamMed(examMed);
//        dtmExamMed.addRow(examMed.getAtributosData().toArray());
    }

    public static void adicionarFerias(Trabalhador trabalhador, Date inicio, Date fim) {
//        if (trabalhador.getFerias() == null) {
//            Ferias ferias = new Ferias();
//            ferias.setTrabalhador(trabalhador);
//            if (ferias.getAtributosData().isEmpty())
//                ferias.setAtributosData(Trabalhadores.getListaAtributoMeses(inicio, fim));
//            trabalhador.setFerias(ferias);
//            dtmFerias.addRow(ferias.getAtributosData().toArray());
//        }
    }

    public static void adicionarRaisCaged(Trabalhador trabalhador, Date inicio, Date fim) {
//        Rais rais = new Rais();
//        rais.setTrabalhador(trabalhador);
//        rais.setTodosAtributosData(Trabalhadores.getListaAtributoAnos(inicio, fim));
//        trabalhador.setRais(rais);
//        CAGED caged = new CAGED();
//        caged.setTrabalhador(trabalhador);
//        caged.setAtributosData(Trabalhadores.getListaAtributoMeses(inicio, fim));
//        trabalhador.setCaged(caged);
    }

    public static void adicionarRescisao(Trabalhador trabalhador, Date inicio, Date fim) {
        Rescisao rescisao = new Rescisao();
        rescisao.setTrabalhador(trabalhador);
        rescisao.setAvisoPrevio(Trabalhadores.getListaAtributoAnos(inicio, fim));
        rescisao.setPedidoDemissao(Trabalhadores.getListaAtributoAnos(inicio, fim));
        rescisao.setTermo(Trabalhadores.getListaAtributoAnos(inicio, fim));
        trabalhador.setRescisao(rescisao);
    }

    public static void adicionarVinculo(Trabalhador trabalhador) {

//        dtmTrabalhadores.addRow(new Object[]{trabalhador.getNome(), trabalhador.getPis(),
//                    trabalhador.getAdmissao(), trabalhador.getAfastamento(),
//                    trabalhador.getCodAfastamento(), trabalhador.isAprendiz(),
//                    trabalhador.getGenero()});
//        int size = trabalhadores.size();
//        if (size > 0)
//            dtmTrabalhadores.fireTableRowsInserted(size - 1, size - 1);
//        else
//            dtmTrabalhadores.fireTableRowsInserted(0, size - 1);
        dtmTrabalhadores.fireTableDataChanged();
    }

    public static void adicionarRegistro(Trabalhador trabalhador) {
        if (trabalhador.getLivro() == null) {
            LRE livro = new LRE();
            trabalhador.setLivro(livro);
        }
        if (trabalhador.getCtps() == null) {
            Atributo ctps = new Atributo();
            trabalhador.setCtps(ctps);
        }

        dtmRegistro.fireTableDataChanged();
    }
}
